package fr.charlott.business.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.dozer.DozerBeanMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import fr.charlott.business.dto.ClienteDTO;
import fr.charlott.business.dto.HotesseDTO;
import fr.charlott.business.dto.ProduitDTO;
import fr.charlott.business.dto.ReunionDTO;
import fr.charlott.business.service.ClienteService;
import fr.charlott.business.service.HotesseService;
import fr.charlott.business.service.ReunionService;
import fr.charlott.core.repository.model.Hotesse;
import fr.charlott.core.repository.model.Produit;
import fr.charlott.tools.exceptions.FunctionalException;

@Service("hotesseService")
public class HotesseServiceImpl implements HotesseService {

    private fr.charlott.core.service.HotesseService hotesseService;

    private fr.charlott.core.service.ProduitService produitService;

    private ClienteService clienteService;

    private ReunionService reunionService;

    private DozerBeanMapper dozerMapper;

    public HotesseServiceImpl() {
        super();
    }

    @Autowired
    public HotesseServiceImpl(fr.charlott.core.service.HotesseService hotesseService, fr.charlott.core.service.ProduitService produitService,
            ClienteService clienteService, ReunionService reunionService, DozerBeanMapper dozerMapper) {
        this();
        this.hotesseService = hotesseService;
        this.produitService = produitService;
        this.clienteService = clienteService;
        this.reunionService = reunionService;
        this.dozerMapper = dozerMapper;
    }

    @Override
    @Transactional
    public void ajouterHotesse(HotesseDTO hotesseDTO) {
        hotesseService.ajouterHotesse(dozerMapper.map(hotesseDTO, Hotesse.class));
    }

    @Override
    @Transactional
    public void importerHotesse(HotesseDTO hotesseDTO) {
        List<Produit> produits = new ArrayList<Produit>();
        for (ProduitDTO produitDTO : hotesseDTO.getProduits()) {
            Produit produit = produitService.ajouterProduit(dozerMapper.map(produitDTO, Produit.class));
            produits.add(produit);
        }

        Hotesse hotesse = dozerMapper.map(hotesseDTO, Hotesse.class);
        hotesse.setProduits(produits);
        hotesseService.ajouterHotesse(hotesse);
    }

    @Override
    @Transactional
    public void supprimerHotesse(HotesseDTO hotesseDTO) throws FunctionalException {
        if (hotesseService.chercherParId(hotesseDTO.getId()) != null) {

            List<ClienteDTO> clientes = clienteService.chercherParHotesse(hotesseDTO);
            if (!clientes.isEmpty()) {
                throw new FunctionalException("Cette hotesse est attaché à " + clientes.size() + " cliente(s)");
            }

            List<ReunionDTO> reunions = reunionService.chercherParHotesse(hotesseDTO);
            if (!reunions.isEmpty()) {
                throw new FunctionalException("Cette hotesse est attaché à " + reunions.size() + " reunion(s)");
            }

            hotesseService.supprimerHotesse(dozerMapper.map(hotesseDTO, Hotesse.class));
        }
    }

    @Override
    @Transactional
    public void supprimerToutesLesHotesses() {
        hotesseService.supprimerToutesLesHotesses();
    }

    @Override
    @Transactional
    public HotesseDTO chercherParId(Long id) {
        Hotesse hotesse = hotesseService.chercherParId(id);
        if (hotesse != null) {
            return dozerMapper.map(hotesse, HotesseDTO.class);
        }
        return null;
    }

    @Override
    @Transactional(readOnly = true)
    public HotesseDTO chercherParNomPrenom(String nom, String prenom) {
        Hotesse hotesse = hotesseService.chercherParNomPrenom(nom, prenom);
        if (hotesse != null) {
            return dozerMapper.map(hotesse, HotesseDTO.class);
        }
        return null;
    }

    @Override
    @Transactional(readOnly = true)
    public List<HotesseDTO> chargerToutesLesHotesses() {
        List<HotesseDTO> listeHotesses = new ArrayList<HotesseDTO>();
        for (Hotesse hotesse : hotesseService.chargerToutesLesHotesses()) {
            listeHotesses.add(dozerMapper.map(hotesse, HotesseDTO.class));
        }
        return listeHotesses;
    }

    // getters - setters

    /**
     * @param dozerMapper
     *            the dozerMapper to set
     */
    public void setDozerMapper(DozerBeanMapper dozerMapper) {
        this.dozerMapper = dozerMapper;
    }

    /**
     * @param hotesseService
     *            the hotesseService to set
     */
    public void setHotesseService(fr.charlott.core.service.HotesseService hotesseService) {
        this.hotesseService = hotesseService;
    }

}
